package com.linzm.leetcode.mid.exercises2_20230211;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author zimingl
 * @Date 2023/2/26 14:55
 * @Description: 前K个高频单词
 */
public class Demo11_692 {
    public static void main(String[] args) {
//        String[] words = {"the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"};
        String[] words = { "i", "love", "leetcode", "i", "love", "coding"};
        int k = 2;
        Demo11_692 demo11_692 = new Demo11_692();
        List<String> list = demo11_692.topKFrequent3(words, k);
        System.out.println(list);
    }

    public List<String> topKFrequent(String[] words, int k) {
        Map<String, Integer> map = new LinkedHashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
        LinkedHashMap<String, Integer> sortedMap = map
                .entrySet().stream()
                .sorted(Map.Entry.comparingByValue((num1, num2) -> num2 - num1))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k1, LinkedHashMap::new));
        List<String> res = new ArrayList<>();
        ArrayList<String> strings = new ArrayList<>(sortedMap.keySet());
        int num = 0;
        while (num < k) {
            res.add(strings.get(num));
            num++;
        }
        return res;
    }

    public List<String> topKFrequent2(String[] words, int k) {
        return Arrays.stream(words)
                // 并行流
                .parallel()
                // 该操作返回一个map，把传入的words进行分组，word作为key，word的数量作为value
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                // 返回Set<Map.Entry>
                .entrySet()
                // 重新生成并行流
                .parallelStream()
                // 进行排序操作
                .sorted(Comparator.<Map.Entry<String, Long>>comparingLong(Map.Entry::getValue).reversed().thenComparing(Map.Entry::getKey))
                // 截取前k个
                .limit(k)
                // 映射,只需要key
                .map(Map.Entry::getKey)
                // 生成list
                .collect(Collectors.toList());
    }

    public List<String> topKFrequent3(String[] words, int k) {
        Map<String, Integer> cnt = new HashMap<>();
        for (String s : words) cnt.put(s, cnt.getOrDefault(s, 0) + 1);
        List<String> ans = new ArrayList<>(cnt.keySet());
        ans.sort((a, b) -> cnt.get(a) > cnt.get(b) ? -1 : (cnt.get(a) < cnt.get(b) ? 1 : a.compareTo(b)));
        return ans.subList(0, k);
    }
}
